<template>
  <div class="search-input-container">
    <el-input
      v-model="searchQuery"
      :placeholder="placeholder"
      :size="size"
      :clearable="clearable"
      :disabled="disabled || isSearching"
      class="search-input"
      @clear="handleClear"
      @keyup.enter="handleEnterSearch"
    >
      <template #prefix>
        <el-icon class="search-icon">
          <Search v-if="!isSearching" />
          <Loading v-else class="loading-icon" />
        </el-icon>
      </template>
      <template v-if="showSearchButton" #append>
        <el-button 
          :icon="Search" 
          :loading="isSearching"
          @click="handleButtonSearch"
        />
      </template>
    </el-input>
    
    <!-- 搜索建议 -->
    <div 
      v-if="showSuggestions && suggestions.length > 0" 
      class="suggestions-dropdown"
    >
      <div
        v-for="(suggestion, index) in suggestions"
        :key="index"
        class="suggestion-item"
        :class="{ active: activeSuggestionIndex === index }"
        @click="handleSuggestionClick(suggestion)"
        @mouseenter="activeSuggestionIndex = index"
      >
        <slot name="suggestion" :suggestion="suggestion" :index="index">
          {{ suggestion }}
        </slot>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import { Search, Loading } from '@element-plus/icons-vue'
import { useSearchDebounce } from '@/common/composables/useDebounceThrottle'

interface Props {
  modelValue?: string
  placeholder?: string
  size?: 'large' | 'default' | 'small'
  clearable?: boolean
  disabled?: boolean
  debounceDelay?: number
  showSearchButton?: boolean
  showSuggestions?: boolean
  suggestions?: string[]
  minLength?: number
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'search', query: string): void
  (e: 'clear'): void
  (e: 'suggestion-click', suggestion: string): void
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  placeholder: '请输入搜索关键词',
  size: 'default',
  clearable: true,
  disabled: false,
  debounceDelay: 500,
  showSearchButton: false,
  showSuggestions: false,
  suggestions: () => [],
  minLength: 1
})

const emit = defineEmits<Emits>()

const searchQuery = ref(props.modelValue)
const activeSuggestionIndex = ref(-1)

// 使用搜索防抖
const { isSearching } = useSearchDebounce(
  async (query: string) => {
    if (query.length >= props.minLength) {
      emit('search', query)
    }
  },
  props.debounceDelay
)

// 监听外部值变化
watch(() => props.modelValue, (newValue) => {
  searchQuery.value = newValue
})

// 监听内部值变化
watch(searchQuery, (newValue) => {
  emit('update:modelValue', newValue)
  activeSuggestionIndex.value = -1
})

const handleClear = () => {
  searchQuery.value = ''
  emit('clear')
}

const handleEnterSearch = () => {
  if (activeSuggestionIndex.value >= 0 && props.suggestions.length > 0) {
    handleSuggestionClick(props.suggestions[activeSuggestionIndex.value])
  } else {
    emit('search', searchQuery.value)
  }
}

const handleButtonSearch = () => {
  emit('search', searchQuery.value)
}

const handleSuggestionClick = (suggestion: string) => {
  searchQuery.value = suggestion
  activeSuggestionIndex.value = -1
  emit('suggestion-click', suggestion)
  emit('search', suggestion)
}

// 键盘导航
const handleKeydown = (event: KeyboardEvent) => {
  if (!props.showSuggestions || props.suggestions.length === 0) return

  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault()
      activeSuggestionIndex.value = Math.min(
        activeSuggestionIndex.value + 1,
        props.suggestions.length - 1
      )
      break
    case 'ArrowUp':
      event.preventDefault()
      activeSuggestionIndex.value = Math.max(
        activeSuggestionIndex.value - 1,
        -1
      )
      break
    case 'Escape':
      activeSuggestionIndex.value = -1
      break
  }
}

// 添加键盘事件监听
nextTick(() => {
  document.addEventListener('keydown', handleKeydown)
})
</script>

<style scoped>
.search-input-container {
  position: relative;
  width: 100%;
}

.search-input {
  width: 100%;
}

.search-icon {
  color: var(--el-text-color-placeholder);
}

.loading-icon {
  animation: rotate 2s linear infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.suggestions-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--el-bg-color-overlay);
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
  box-shadow: var(--el-box-shadow-light);
  z-index: 1000;
  max-height: 200px;
  overflow-y: auto;
}

.suggestion-item {
  padding: 8px 12px;
  cursor: pointer;
  transition: background-color 0.2s;
  border-bottom: 1px solid var(--el-border-color-lighter);
}

.suggestion-item:last-child {
  border-bottom: none;
}

.suggestion-item:hover,
.suggestion-item.active {
  background-color: var(--el-fill-color-light);
}
</style>